<?php

namespace app\admin\service;

use app\admin\model\Role;
use common\enum\ResultCode;
use Tinywan\ExceptionHandler\Exception\BadRequestHttpException;
use Tinywan\ExceptionHandler\Exception\NotFoundHttpException;
use Webman\Event\Event;

class RoleService extends BaseCurdService
{
    /**
     * 获取角色列表
     * @param array $params 查询参数
     * @return array
     */
    public function getList(array $params): array
    {
        $query = Role::query();
        return $this->paginateQuery($query, $params, ['name'], ['status']);
    }

    /**
     * 获取角色详情
     * @param int $id 角色ID
     * @return Role|null
     */
    public function getInfo(int $id): ?Role
    {
        $role = Role::find($id);
        if (!$role) {
            throw new NotFoundHttpException(ResultCode::DATA_NOT_FOUND->getDescription());
        }
        return $role;
    }

    /**
     * 创建角色
     * @param array $data 角色数据
     * @return Role
     */
    public function create(array $data): Role
    {
        // 检查角色名称是否已存在
        if (Role::where('name', $data['name'])->exists()) {
            throw new BadRequestHttpException('角色名称已存在');
        }
        return Role::create($data);
    }

    /**
     * 更新角色
     * @param int $id 角色ID
     * @param array $data 更新数据
     * @return bool
     */
    public function update(int $id, array $data): bool
    {
        $role = Role::find($id);
        if (!$role) {
            throw new NotFoundHttpException(ResultCode::DATA_NOT_FOUND->getDescription());
        }
        // 检查角色名称是否已存在
        if (isset($data['name']) && Role::where('name', $data['name'])->where('id', '!=', $id)->exists()) {
            throw new BadRequestHttpException('角色名称已存在');
        }
        $result = $role->update($data);
        if ($result) {
            Event::emit('role.updated', ['roleId' => $id]);
        }
        return $result;
    }

    /**
     * 删除角色
     * @param int $id 角色ID
     * @return bool|null
     */
    public function delete(int $id): ?bool
    {
        $role = Role::find($id);
        if (!$role) {
            throw new NotFoundHttpException(ResultCode::DATA_NOT_FOUND->getDescription());
        }
        // 检查是否有管理员关联此角色
        if ($role->admins()->exists()) {
            throw new BadRequestHttpException('该角色下有管理员，无法删除');
        }
        $result = $role->delete();
        if ($result) {
            Event::emit('role.deleted', ['roleId' => $id]);
        }
        return $result;
    }

    /**
     * 角色授权菜单
     * @param int $roleId 角色ID
     * @param array $menuIds 菜单ID列表
     * @return array|array[]
     */
    public function grantMenus(int $roleId, array $menuIds): array
    {
        $role = Role::find($roleId);
        if (!$role) {
            throw new NotFoundHttpException(ResultCode::DATA_NOT_FOUND->getDescription());
        }
        // 同步角色和菜单关联
        $result = $role->menus()->sync($menuIds);
        Event::emit('role.menus.granted', ['roleId' => $roleId]);
        return $result;
    }
}